//=============================================================================
/**
 *
 *	@file		drop_sub.c
 *	@brief		ポケスリング 上画面
 *	@author		hosaka genya
 *	@data		2009.01.07
 *
 */
//=============================================================================
#include "common.h"
#include "strbuf_family.h"
#include "system/clact_tool.h"
#include "system/gra_tool.h"
#include "system/msgdata_util.h"
#include "system/wordset.h"
#include "system/fontproc.h"

#include "poketool/pokeicon.h"

#include "msgdata/msg.naix"
#include "msgdata/msg_pokethlon.h"

#include "../../pkthln_comm_pack.h"
#include "../../pkthln_obj_common.h"
#include "../../pokethlon.h"
#include "../../cmn_res.h"
#include "../evt_cats.h"

#include "pkthln_drop.h"
#include "drop_define.h"
#include "drop_sub.h"

//=============================================================================
/**
 *								定数定義
 */
//=============================================================================

#define POINT_NUMBER_W	(4)			//数字横キャラ幅
#define POINT_NUMBER_H	(8)			//数字縦キャラ幅
#define POINT_DIGI_MAX	(3)			//得点は最大3桁
#define POINT_DISP_START_X	(16)	//数描画開始X位置（キャラ）
#define POINT_DISP_START_Y	(11)	//数描画開始Y位置（キャラ）
#define NUMBER_SCR_NUM_W	(5)		//数字スクリーンデータの横の数字の数0〜4	スクリーンデータに依存
#define NUMBER_SCR_NUM_H	(2)		//数字スクリーンデータの縦の数字の数5〜9	スクリーンデータに依存

//--------------------------------------------------------------
///	CAP_ID
//==============================================================
typedef enum {
	TIME_FIGRE = 2,
	TIME_CAP_DIFF_X = 4,	///< 時間アイコンと時間表記の間ドット
	TIME_ICON_X = 15*8 - 2 - TIME_CAP_DIFF_X,
	TIME_ICON_Y = 22*8 + 4,

	CAP_FLAG_X = 17*8 - 2,
	CAP_FLAG_Y = 20*8,
	CAP_POKEICON_ST_X = 8 * 15,
	CAP_POKEICON_ST_Y = 8 * 4 + 4,
	CAP_POKE_MAX = ENTRY_MEMBER_NUM_MAX,
	CAP_RANK_MAX = ENTRY_MEMBER_NUM_MAX,
	CAP_PKGR_MAX = OBJ_POKEGRA_S_MAX,		///< ポケグラ数

	CAP_ID_FLAG = 0,
	CAP_ID_TIME_ICON,
	CAP_ID_POKE_HEAD,
	CAP_ID_POKE_END = CAP_ID_POKE_HEAD + CAP_POKE_MAX,
	CAP_ID_BALL_HEAD = CAP_ID_POKE_END,
	CAP_ID_BALL_END = CAP_ID_BALL_HEAD + CAP_POKE_MAX,
	CAP_ID_RANK_HEAD = CAP_ID_BALL_END,
	CAP_ID_RANK_END = CAP_ID_RANK_HEAD + CAP_RANK_MAX,
	CAP_ID_PKGR_HEAD = CAP_ID_RANK_END,
	CAP_ID_PKGR_END = CAP_ID_PKGR_HEAD + CAP_PKGR_MAX,
	CAP_ID_PKGR_EFF_HEAD = CAP_ID_PKGR_END,
	CAP_ID_PKGR_EFF_END = CAP_ID_PKGR_EFF_HEAD + CAP_PKGR_MAX,
	CAP_ID_MAX = CAP_ID_PKGR_EFF_END,
} CAP_ID;

//--------------------------------------------------------------
///
//==============================================================
enum
{
	WIN_ID_S_TRNAME,
	WIN_ID_S_POKENICK,
	WIN_ID_S_SCORE_CAP,
	WIN_ID_MAX,
};


#define BMP_STRING_H (2)

#define BMP_S_TRNAME_W (10)
#define BMP_S_POKENICK_W (15)
#define BMP_S_SCORE_CAP_W (10)

#define BMP_S_TRNAME_CGX (1)
#define BMP_S_POKENICK_CGX ( BMP_S_TRNAME_CGX + BMP_S_TRNAME_W * BMP_STRING_H )
#define BMP_S_SCORE_CAP_CGX ( BMP_S_POKENICK_CGX + BMP_S_POKENICK_W * BMP_STRING_H )


static const BMPWIN_DAT c_DropBmpWinDat[ WIN_ID_MAX ] =
{
	{ BG_FRM_S_TEXT, 18, 19, BMP_S_TRNAME_W,	BMP_STRING_H, SUB_FONT_PAL,  BMP_S_TRNAME_CGX },
	{ BG_FRM_S_TEXT,  0, 22, BMP_S_POKENICK_W,	BMP_STRING_H, SUB_FONT_PAL,  BMP_S_POKENICK_CGX },
	{ BG_FRM_S_TEXT, 14, 9, BMP_S_SCORE_CAP_W,	BMP_STRING_H, SUB_FONT_PAL,  BMP_S_SCORE_CAP_CGX },
};



//=============================================================================
/**
 *								構造体定義
 */
//=============================================================================
//--------------------------------------------------------------
///	SUB画面 コントローラー
//==============================================================
typedef struct DROP_SUB_CNT_tag {
	// [IN]
	PKTHLN_PTR work;
	HEAPID HeapID;
	CATS_SYS_PTR csp;
	CATS_RES_PTR crp;
	CMN_RES_CNT_PTR CmnResCntPtr;
	GF_BGL_INI* bgl;
	MSGDATA_MANAGER* MsgMan;
	WORDSET* WordSet;
	u16 PlttOfsPokeIcon;
	u8 NetID;
	u8 DummyBit;
	// [PRIVATE]
	ARCHANDLE* pArcPokeIcon;
	void* PointBgArc;
	NNSG2dScreenData* PointScrnData;
	GF_BGL_BMPWIN Win[ WIN_ID_MAX ];
	CATS_ACT_PTR cap[ CAP_ID_MAX ];
	CLACT_WORK_PTR actTime[ TIME_FIGRE ];
	STRBUF* NickName[ ENTRY_MAX ];	///< ポケモンニックネーム
	s8 PokeGraNpcCnt[ ENTRY_MEMBER_NUM_MAX ];	///< NPCのポケグラ交換エミュレート用カウンタ
	u8 PokeGraChgSeq;				///< ポケグラ交代用シーケンサ
	u8 time_color;					///< 時間OBJの色変化SEQ
	u16 DispScore;					///< 表示しているスコア値
	BOOL bRankOff;
} DROP_SUB_CNT;

//=============================================================================
/**
 *							プロトタイプ宣言
 */
//=============================================================================
// prototype
DROP_SUB_CNT_PTR DropSub_Create( CATS_SYS_PTR csp, CATS_RES_PTR crp, CMN_RES_CNT_PTR CmnResCntPtr, GF_BGL_INI* bgl, MSGDATA_MANAGER* mm, WORDSET* wset, u8 NetID, HEAPID HeapID, PKTHLN_PTR work );
void DropSub_Init( DROP_SUB_CNT_PTR ptr );
void DropSub_Delete( DROP_SUB_CNT_PTR ptr );
void DropSub_Finish( DROP_SUB_CNT_PTR ptr );
void DropSub_AddScore( DROP_SUB_CNT_PTR ptr, u8 NetID, u16 Score, RANK_DATA* pRank );
void DropSub_DispTime( DROP_SUB_CNT_PTR ptr, const int inTime );
void DropSub_DispStamina( DROP_SUB_CNT_PTR ptr, BOOL bSweat_1, BOOL bSweat_2 );
u16 DropSub_GetDispScore( DROP_SUB_CNT_PTR ptr );
BOOL DropSub_ChangePokeMain( DROP_SUB_CNT_PTR ptr, u8 NetID, u8 PokeID );
BOOL DropSub_ChangePokeNpc( DROP_SUB_CNT_PTR ptr, u8 NetID, u8 PokeID );
void DropSub_SetPokeIconOrBall( DROP_SUB_CNT_PTR ptr, u8 NetID, u8 PokeID, BOOL bBall );
static CATS_ACT_PTR OBJ_AddCapSub( CATS_SYS_PTR csp, CATS_RES_PTR crp, s16 px, s16 py, u16 anime, u16 pri );
static void CreateBmpWin( DROP_SUB_CNT_PTR ptr );
static void BG_FillPoint(DROP_SUB_CNT_PTR ptr, const u8 inPoint);
static void BG_PrintFirst( DROP_SUB_CNT_PTR ptr );
static void BMPWIN_Print( GF_BGL_BMPWIN* win, WORDSET* WordSet, MSGDATA_MANAGER* MsgMan, u32 msgIdx, u32 HeapID );
static void BMPWIN_PrintEx( GF_BGL_BMPWIN* win, WORDSET* WordSet, MSGDATA_MANAGER* MsgMan, u32 msgIdx, u32 HeapID, s16 ofs_x, s16 ofs_y );
static void OBJ_Init( DROP_SUB_CNT_PTR ptr );
static void OBJ_TransPokeGra( PKTHLN_PTR work, HEAPID HeapID, CATS_ACT_PTR cap, u8 NetID, u8 PokeID );
static void OBJ_TransPokeIcon( DROP_SUB_CNT_PTR ptr, u8 NetID, u8 PokeIdx );
static CATS_ACT_PTR OBJ_AddCapMain( CATS_SYS_PTR csp, CATS_RES_PTR crp, s16 px, s16 py, u16 anime, u16 pri );
static void OBJ_CreateTime( DROP_SUB_CNT_PTR ptr );
static void ChangePokeName( DROP_SUB_CNT_PTR ptr, u8 PokeID );
static void SetBenchPokePos( DROP_SUB_CNT_PTR ptr, u32 capID, s16 px, s16 py );
static void SetPokeIconState( DROP_SUB_CNT_PTR ptr, u8 NetID, BOOL bBall );


//=============================================================================
/**
 *								外部公開関数
 */
//=============================================================================

//-----------------------------------------------------------------------------
/**
 *	@brief	サブ画面管理モジュール生成
 *
 *	@param	DROP_SUB_CNT_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
DROP_SUB_CNT_PTR DropSub_Create( CATS_SYS_PTR csp, CATS_RES_PTR crp, CMN_RES_CNT_PTR CmnResCntPtr, GF_BGL_INI* bgl, MSGDATA_MANAGER* mm, WORDSET* wset, u8 NetID, HEAPID HeapID, PKTHLN_PTR work )
{
	int i;
	DROP_SUB_CNT_PTR ptr;

	GF_ASSERT(csp);
	GF_ASSERT(crp);
	GF_ASSERT(CmnResCntPtr);
	GF_ASSERT(bgl);
	GF_ASSERT(mm);
	GF_ASSERT(wset);

	ptr = sys_AllocMemory( HeapID, sizeof(DROP_SUB_CNT) );
	MI_CpuClear8( ptr, sizeof(DROP_SUB_CNT) );

	ptr->csp = csp;
	ptr->crp = crp;
	ptr->CmnResCntPtr = CmnResCntPtr;
	ptr->NetID = NetID;
	ptr->HeapID = HeapID;
	ptr->bgl = bgl;
	ptr->MsgMan = mm;
	ptr->WordSet = wset;
	ptr->work = work;

	ptr->pArcPokeIcon = ArchiveDataHandleOpen( ARC_POKEICON, ptr->HeapID );

	// BGスコア用リソースロード
	ptr->PointBgArc = ArcUtil_ScrnDataGet(ARC_PKTHEV_DROP, NARC_pkthev_drop_drop_bg_point_lz_NSCR,
						TRUE, &ptr->PointScrnData, ptr->HeapID);

	// ポケアイコン パレットを転送
	ptr->PlttOfsPokeIcon =
		CATS_LoadResourcePlttArc( csp, crp, ARC_POKEICON,
			PokeIconPalArcIndexGet(), 0, POKEICON_PAL_MAX,
			NNS_G2D_VRAM_TYPE_2DSUB, PAL_ID_S_POKEICON );

	// ニックネーム メモリ確保/取得
	{
		POKETHLON_ENTRY_DATA* entry;
		entry = PTFrame_GetEntryDataPtrByID( work, PTFrameGetCurrentID(work));
		for( i=0; i<ENTRY_MAX; i++ )
		{
			ptr->NickName[i] = STRBUF_Create( MONS_NAME_SIZE + EOM_SIZE, ptr->HeapID );
			STRBUF_SetStringCode( ptr->NickName[i], entry[i].NickName );
		}
	}

	CreateBmpWin( ptr );

	return ptr;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	サブ画面管理モジュール 初期化
 *
 *	@param	DROP_SUB_CNT_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void DropSub_Init( DROP_SUB_CNT_PTR ptr )
{
	// OBJ初期化
	OBJ_Init( ptr );

	// 表示時間初期化
	DropSub_DispTime( ptr, GAME_TIME/GAME_FPS );

	// BGスコア初期化
	BG_FillPoint( ptr, 0 );

	BG_PrintFirst( ptr );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	サブ画面管理モジュール 削除
 *
 *	@param	DROP_SUB_CNT_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void DropSub_Delete( DROP_SUB_CNT_PTR ptr )
{
	int i;

	GF_ASSERT( ptr );

	ArchiveDataHandleClose( ptr->pArcPokeIcon );

	// ニックネームメモリ開放
	for( i=0; i<ENTRY_MAX; i++ )
	{
		STRBUF_Delete( ptr->NickName[i] );
	}

	// スクリーンアーカインブ開放
	sys_FreeMemoryEz( ptr->PointBgArc );

	// BMPWIN開放
	for( i=0; i<WIN_ID_MAX; i++ )
	{
		GF_BGL_BmpWinDel( &ptr->Win[i] );
	}

	// CAP開放
	for( i=0; i<CAP_ID_MAX; i++ )
	{
		GF_ASSERT( ptr->cap[i] );
		CATS_ActorPointerDelete_S( ptr->cap[i] );
	}

	sys_FreeMemoryEz( ptr );
}


//-----------------------------------------------------------------------------
/**
 *	@brief	サブ画面管理モジュール 終了
 *
 *	@param	DROP_SUB_CNT_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void DropSub_Finish( DROP_SUB_CNT_PTR ptr )
{
	int i;

	// アニメ停止
	for( i=0; i<CAP_PKGR_MAX; i++ )
	{
		CATS_ObjectAutoAnimeSetCap( ptr->cap[ CAP_ID_PKGR_EFF_HEAD + i ], FALSE );
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief	指定チームの加点演出
 *
 *	@param	DROP_SUB_CNT_PTR ptr
 *	@param	NetID
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void DropSub_AddScore( DROP_SUB_CNT_PTR ptr, u8 NetID, u16 Score, RANK_DATA* pRank )
{
	int i;

	GF_ASSERT( ptr );
	GF_ASSERT( NetID < ENTRY_MEMBER_NUM_MAX );

	// 順位判定
	{
		int rnk = 0;

		for( i=0; i<ENTRY_MEMBER_NUM_MAX; i++ )
		{
			u8 NetID = pRank[i].NetID;

			CATS_ObjectAnimeSeqCheckSetCap( ptr->cap[ CAP_ID_RANK_HEAD + NetID ], NANR_drop_obj_sub_rank1 + rnk );

			if( i != ENTRY_MEMBER_NUM_MAX-1 )
			{
				// 次の項目と比較して、同点じゃなければ順位を更新
				if( pRank[i].Score != pRank[i+1].Score )
				{
					rnk = i+1;
				}
			}
		}
	}

	// 自分のスコアのみ反映
	if( NetID == PTFrameGetCurrentID(ptr->work) )
	{
		// 差異があるときのみ更新
		if( Score != ptr->DispScore )
		{
			BG_FillPoint( ptr, Score );
			ptr->DispScore = Score;
		}
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief	指定時間を表示
 *
 *	@param	DROP_SUB_CNT_PTR ptr
 *	@param	int inTime
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void DropSub_DispTime( DROP_SUB_CNT_PTR ptr, const int inTime )
{
	u8 sec,sec_t,sec_o;

	//秒計算
	sec = inTime % 100;

	sec_t = sec / 10;
	sec_o = sec % 10;

	ptr->bRankOff = ( inTime < RANK_OFF_TIME || inTime > RANK_ON_TIME );

	// 順位表示切替
	{
		int i;
		for(i=0;i<ENTRY_MEMBER_NUM_MAX;i++)
		{
			CATS_ObjectEnableCap( ptr->cap[ CAP_ID_RANK_HEAD + i ], !ptr->bRankOff );
		}
	}

	//秒を書き換え
	CLACT_AnmChg( ptr->actTime[0], sec_t + 1 );
	CLACT_AnmChg( ptr->actTime[1], sec_o + 1 );
//	CATS_ObjectAnimeSeqSetCap(ptr->cap[ CAP_ID_NUM_HEAD + 0 ], sec_t + NANR_drop_obj_main_num0 );
//	CATS_ObjectAnimeSeqSetCap(ptr->cap[ CAP_ID_NUM_HEAD + 1 ], sec_o + NANR_drop_obj_main_num0 );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	控えポケモンのスタミナ情報を表示
 *
 *	@param	DROP_SUB_CNT_PTR ptr
 *	@param	Sta1
 *	@param	Sta2
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void DropSub_DispStamina( DROP_SUB_CNT_PTR ptr, BOOL bSweat_1, BOOL bSweat_2 )
{
	CATS_ObjectEnableCap( ptr->cap[CAP_ID_PKGR_EFF_HEAD], bSweat_1 );
	CATS_ObjectEnableCap( ptr->cap[CAP_ID_PKGR_EFF_HEAD+1], bSweat_2 );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	ローカル得点情報を取得
 *
 *	@param	DROP_SUB_CNT_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
u16 DropSub_GetDispScore( DROP_SUB_CNT_PTR ptr )
{
	return ptr->DispScore;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	交代デモ：ポケグラ交換
 *
 *	@param	DROP_SUB_CNT_PTR ptr
 *	@param	NetID
 *	@param	PokeID
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
BOOL DropSub_ChangePokeMain( DROP_SUB_CNT_PTR ptr, u8 NetID, u8 PokeID )
{
	u8 MyNetID = PTFrameGetCurrentID(ptr->work);
	u8 NextID = (PokeID+1) % ENTRY_MAX;		// 交代後のIDを取得

	switch( ptr->PokeGraChgSeq )
	{
		case 0:
			// ポケグラ アウト
			{
				s16 px, py, my;

				CATS_ObjectPosGetCap_SubSurface( ptr->cap[ CAP_ID_PKGR_HEAD+1 ], &px, &py, OBJ_DISTANCE );

				HOSAKA_PRINT( "pokegra py:%d \n",py );

				// 捌ける
				if( py < 216 )
				{
					my = MATH_IAbs(BENCH_POKE_OUT_Y - py) >> 2;
					py += my;
					if( py > 216 ){ py = 216; }
					SetBenchPokePos( ptr, CAP_ID_PKGR_HEAD+1, px, py );
				}
				else
				{
					// ベンチポケグラの位置をセット
					px = BENCH_POKE_X;
					py = BENCH_POKE_Y - BENCH_POKE_Y_OFS;
					SetBenchPokePos( ptr, CAP_ID_PKGR_HEAD+1, px, py );
					// 次SEQでINするポケモンをロード
					OBJ_TransPokeGra( ptr->work, ptr->HeapID, ptr->cap[ CAP_ID_PKGR_HEAD+1 ], MyNetID, PokeID );
					// 「次のポケモンは〜」を更新
					ChangePokeName( ptr, NextID );
//					SetPokeIconState( ptr, MyNetID, TRUE );

					ptr->PokeGraChgSeq++;
				}
			}
			break;

		case 1:
			// ポケグラ イン
			{
				s16 px, py, my;

				CATS_ObjectPosGetCap_SubSurface( ptr->cap[ CAP_ID_PKGR_HEAD ], &px, &py, OBJ_DISTANCE );
				my  = MATH_IAbs(BENCH_POKE_IN_Y-py) * 3 / 4;

				if( BENCH_POKE_IN_Y >= py )
				{
					if( my == 0 ){ my = 1; } // 誤差調整
					// ポケモン1
					py += my;
					SetBenchPokePos( ptr, CAP_ID_PKGR_HEAD, px, py );
					// ポケモン2
					CATS_ObjectPosGetCap_SubSurface( ptr->cap[ CAP_ID_PKGR_HEAD+1 ], &px, &py, OBJ_DISTANCE );
					py += my;
					SetBenchPokePos( ptr, CAP_ID_PKGR_HEAD+1, px, py );
				}
				else
				{
					// 移動終了
					{
						// ベンチポケグラ アクターの参照先交換
						CATS_ACT_PTR capTemp;
						// ポケ
						capTemp = ptr->cap[ CAP_ID_PKGR_HEAD ];
						ptr->cap[ CAP_ID_PKGR_HEAD ] = ptr->cap[ CAP_ID_PKGR_HEAD+1 ];
						ptr->cap[ CAP_ID_PKGR_HEAD+1 ] = capTemp;
						// 状態異常アイコン
						capTemp = ptr->cap[ CAP_ID_PKGR_EFF_HEAD ];
						ptr->cap[ CAP_ID_PKGR_EFF_HEAD ] = ptr->cap[ CAP_ID_PKGR_EFF_HEAD+1 ];
						ptr->cap[ CAP_ID_PKGR_EFF_HEAD+1 ] = capTemp;
						// 座標を強制置換
						SetBenchPokePos( ptr, CAP_ID_PKGR_HEAD, BENCH_POKE_X, BENCH_POKE_Y );
						SetBenchPokePos( ptr, CAP_ID_PKGR_HEAD+1, BENCH_POKE_X, BENCH_POKE_Y + BENCH_POKE_Y_OFS );
					}
					ptr->PokeGraChgSeq++;
				}

			}
			break;

		case 2 :
			// 終了
			ptr->PokeGraChgSeq = 0;
			return TRUE;

		default : GF_ASSERT(0);
	}

	return FALSE;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	交代デモ：NPC用のポケグラ交換ダミー処理
 *
 *	@param	DROP_SUB_CNT_PTR ptr
 *	@param	NetID
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
BOOL DropSub_ChangePokeNpc( DROP_SUB_CNT_PTR ptr, u8 NetID, u8 PokeID )
{
	GF_ASSERT((0<NetID)&&(NetID<ENTRY_MEMBER_NUM_MAX));

	ptr->PokeGraNpcCnt[NetID]++;

	if( ptr->PokeGraNpcCnt[NetID] > AI_NPC_PKGR_CNG_SYNC )
	{
		ptr->PokeGraNpcCnt[NetID] = 0;
		return TRUE;
	}

	return FALSE;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	ポケアイコンをセット
 *
 *	@param	DROP_SUB_CNT_PTR ptr
 *	@param	NetID	通信ID
 *	@param	PokeID	ポケID
 *	@param	bBall	ボール状態にするか
 *
 *	@retval	none
 */
//-----------------------------------------------------------------------------
void DropSub_SetPokeIconOrBall( DROP_SUB_CNT_PTR ptr, u8 NetID, u8 PokeID, BOOL bBall )
{
	GF_ASSERT(ptr);
	GF_ASSERT(NetID<ENTRY_MEMBER_NUM_MAX);
	GF_ASSERT(PokeID<ENTRY_MAX);

	if( bBall == FALSE )
	{
		OBJ_TransPokeIcon( ptr, NetID, PokeID );
	}

	SetPokeIconState( ptr, NetID, bBall );
}

//=============================================================================
/**
 *								static関数
 */
//=============================================================================

//-----------------------------------------------------------------------------
/**
 *	@brief	OBJ追加(サブ)
 *
 *	@param	CATS_SYS_PTR csp
 *	@param	crp
 *	@param	px
 *	@param	py
 *	@param	anime
 *	@param	pri
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static CATS_ACT_PTR OBJ_AddCapSub( CATS_SYS_PTR csp, CATS_RES_PTR crp, s16 px, s16 py, u16 anime, u16 pri )
{
	TCATS_OBJECT_ADD_PARAM_S prm = {
		0, 0, 0,
		0, 0, 0, NNS_G2D_VRAM_TYPE_2DSUB,
		{ CHR_ID_SUB, PAL_ID_SUB, CEL_ID_SUB, ANM_ID_SUB },
		1, 0,
	};

	CATS_ACT_PTR cap;

	GF_ASSERT(csp);
	GF_ASSERT(crp);

	prm.x = px;
	prm.y = py;
	prm.anm = anime;
	prm.pri = pri;

	cap = CATS_ObjectAdd_S_SubDistance( csp, crp, &prm, OBJ_DISTANCE );
	CATS_ObjectAutoAnimeSetCap( cap, TRUE );

	return cap;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	BMPWIN生成
 *
 *	@param	DROP_SUB_CNT_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void CreateBmpWin( DROP_SUB_CNT_PTR ptr )
{
	u8 i;

	GF_ASSERT( ptr );
	GF_ASSERT( ptr->bgl );

	for( i=0; i<WIN_ID_MAX; i++ )
	{
		const BMPWIN_DAT* dat = &c_DropBmpWinDat[i];

		GF_BGL_BmpWinAddEx( ptr->bgl, &(ptr->Win[i]), dat );
	}

	//先頭キャラをクリア（スクリーンクリアされてるところは、このキャラで埋まる）
	GF_BGL_CharFill( ptr->bgl, BG_FRM_S_TEXT, 0, 1, 0 );

	//システム用フォントパレット転送
	SystemFontPaletteLoad(PALTYPE_SUB_BG, SUB_FONT_PAL*0x20, ptr->HeapID);
}

//-----------------------------------------------------------------------------
/**
 *	@brief	点数のフィル
 *
 *	@param	ptr
 *	@param	u8 inPoint
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void BG_FillPoint(DROP_SUB_CNT_PTR ptr, const u8 inPoint)
{
	u8 i;
	u8 h,t,o;
	u8 read_x[POINT_DIGI_MAX];
	u8 read_y[POINT_DIGI_MAX];

	//3桁の点数を3つに分解
	h = inPoint / 100;
	t = (inPoint-(h*100)) / 10;
	o = inPoint % 10;

	//データ読み込み位置を算出(数字スクリーンデータに依存)
	read_x[0] = (h%NUMBER_SCR_NUM_W)*POINT_NUMBER_W;
	read_y[0] = (h/NUMBER_SCR_NUM_W)*POINT_NUMBER_H;
	read_x[1] = (t%NUMBER_SCR_NUM_W)*POINT_NUMBER_W;
	read_y[1] = (t/NUMBER_SCR_NUM_W)*POINT_NUMBER_H;
	read_x[2] = (o%NUMBER_SCR_NUM_W)*POINT_NUMBER_W;
	read_y[2] = (o/NUMBER_SCR_NUM_W)*POINT_NUMBER_H;

	for (i=0;i<POINT_DIGI_MAX;i++)
	{
		GF_BGL_ScrWriteFree(ptr->bgl, BG_FRM_S_SCORE,
		POINT_DISP_START_X+(i*POINT_NUMBER_W), POINT_DISP_START_Y,
		POINT_NUMBER_W, POINT_NUMBER_H,
		&ptr->PointScrnData->rawData,
		read_x[i], read_y[i], POINT_NUMBER_W*NUMBER_SCR_NUM_W, POINT_NUMBER_H*NUMBER_SCR_NUM_H );
	}
	GF_BGL_LoadScreenV_Req(ptr->bgl, BG_FRM_S_SCORE);
}

//-----------------------------------------------------------------------------
/**
 *	@brief	初回テキスト描画
 *
 *	@param	DROP_SUB_CNT_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void BG_PrintFirst( DROP_SUB_CNT_PTR ptr )
{
	STRBUF* name_buf;

	GF_BGL_BmpWinDataFill( &ptr->Win[ WIN_ID_S_TRNAME ], 0 );

	name_buf = MyStatus_CreateNameString( PTFrame_GetMyStatus( ptr->work, ptr->NetID ), ptr->HeapID );
	GF_STR_PrintColor( &ptr->Win[ WIN_ID_S_TRNAME ], FONT_SYSTEM, name_buf, 0, 0, MSG_NO_PUT, COL_N_WHITE, NULL );
	BMPWIN_PrintEx( &ptr->Win[ WIN_ID_S_SCORE_CAP ], ptr->WordSet, ptr->MsgMan, msg_pkthln_score_cap, ptr->HeapID, 2, 2 );
	STRBUF_Delete( name_buf );

	GF_BGL_BmpWinOn( &ptr->Win[ WIN_ID_S_TRNAME ] );

	// ポケモン名 初回表示
	WORDSET_RegisterWord( ptr->WordSet, 0, ptr->NickName[1], PM_NEUTRAL, TRUE, PM_LANG );
	BMPWIN_Print( &ptr->Win[ WIN_ID_S_POKENICK ], ptr->WordSet, ptr->MsgMan, msg_pkthln_run_next, ptr->HeapID );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	BPMWINにテキストを描画
 *
 *	@param	GF_BGL_BMPWIN* win
 *	@param	WordSet
 *	@param	MsgMan
 *	@param	msgIdx
 *	@param	HeapID
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void BMPWIN_Print( GF_BGL_BMPWIN* win, WORDSET* WordSet, MSGDATA_MANAGER* MsgMan, u32 msgIdx, u32 HeapID )
{
	BMPWIN_PrintEx( win, WordSet, MsgMan, msgIdx, HeapID, 0, 0 );
}

// ドット座標指定版版
static void BMPWIN_PrintEx( GF_BGL_BMPWIN* win, WORDSET* WordSet, MSGDATA_MANAGER* MsgMan, u32 msgIdx, u32 HeapID, s16 ofs_x, s16 ofs_y )
{
	STRBUF* str;

	GF_BGL_BmpWinDataFill( win, 0 );

	str = MSGDAT_UTIL_AllocExpandString( WordSet, MsgMan, msgIdx, HeapID );
	GF_STR_PrintColor( win, FONT_SYSTEM, str, ofs_x, ofs_y, MSG_NO_PUT, COL_N_WHITE, NULL );
	STRBUF_Delete( str );
	GF_BGL_BmpWinOn( win );
}


//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	DROP_SUB_CNT_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void OBJ_Init( DROP_SUB_CNT_PTR ptr )
{
	int i;
	TCATS_OBJECT_ADD_PARAM_S prm = {0};
	u8 NetID = ptr->NetID;

	// 旗
	ptr->cap[ CAP_ID_FLAG ] =
		OBJ_AddCapSub( ptr->csp, ptr->crp, CAP_FLAG_X, CAP_FLAG_Y, NANR_drop_obj_sub_flag1 + NetID, PRISUB_FLAG );
	CATS_ObjectPaletteSetCap( ptr->cap[ CAP_ID_FLAG ], CATS_CMN_S_PALOFS+1 );

	for( i=0; i<ENTRY_MEMBER_NUM_MAX; i++ )
	{
		s16 px, py;

		// ポケアイコン
		px = 8 * 15 + ( 8 * 4 * i );
		py = 8 * 4 + 4;

		ptr->cap[ CAP_ID_POKE_HEAD + i ] =
			OBJ_AddCapSub( ptr->csp, ptr->crp, px, py, NANR_drop_obj_sub_poke1 + i, PRISUB_POKEICON );

		OBJ_TransPokeIcon( ptr, i , 0 );

		// ボールアイコン
		ptr->cap[ CAP_ID_BALL_HEAD + i ] =
			OBJ_AddCapSub( ptr->csp, ptr->crp, px, py, NANR_drop_obj_sub_ball, PRISUB_BALL );
		CATS_ObjectEnableCap( ptr->cap[ CAP_ID_BALL_HEAD + i ], CATS_ENABLE_FALSE );

		// 順位アイコン
		px = 8 * 15 + ( 8 * 4 * i );
		py = 8 * 3;

		ptr->cap[ CAP_ID_RANK_HEAD + i ] =
			OBJ_AddCapSub( ptr->csp, ptr->crp, px, py, NANR_drop_obj_sub_rank1 , PRISUB_RANK );
		CATS_ObjectEnableCap( ptr->cap[ CAP_ID_RANK_HEAD + i ], CATS_ENABLE_FALSE );
	}

	// ポケグラ
	for( i=0; i<CAP_PKGR_MAX; i++ )
	{
		prm.id[0] = CHR_ID_S_POKEGRA_1 + i;
		prm.id[1] = PAL_ID_S_POKEGRA_1 + i;
		prm.id[2] = CEL_ID_POKEGRA;
		prm.id[3] = ANM_ID_POKEGRA;
		prm.d_area = NNS_G2D_VRAM_TYPE_2DSUB;
		prm.x = BENCH_POKE_X;
		prm.y = BENCH_POKE_Y + BENCH_POKE_Y_OFS * i;
		prm.pri = PRISUB_POKE_1 + i;
		prm.bg_pri = 2;

		ptr->cap[ CAP_ID_PKGR_HEAD + i ] = CATS_ObjectAdd_S_SubDistance( ptr->csp, ptr->crp, &prm, OBJ_DISTANCE );
		CATS_ObjectAutoAnimeSetCap( ptr->cap[ CAP_ID_PKGR_HEAD + i ], TRUE );
	}

	// ポケグラ用エフェクト
	for(i=0; i<CAP_PKGR_MAX; i++ )
	{
		s16 eff_x, eff_y;

		eff_x = BENCH_POKE_X;
		eff_y = BENCH_POKE_Y + BENCH_POKEEFF_Y_DIFF + BENCH_POKE_Y_OFS * i;
		OBJ_TransPokeGra( ptr->work, ptr->HeapID, ptr->cap[ CAP_ID_PKGR_HEAD + i ], ptr->NetID, 2-i );
		ptr->cap[ CAP_ID_PKGR_EFF_HEAD + i ] = OBJ_AddCapSub( ptr->csp, ptr->crp, eff_x, eff_y, NANR_drop_obj_sub_sweat, PRISUB_POKE_EFF );
		CATS_ObjectEnableCap( ptr->cap[ CAP_ID_PKGR_EFF_HEAD + i ], CATS_ENABLE_FALSE );
	}

	OBJ_CreateTime( ptr );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	ポケグラを転送
 *
 *	@param	CapIdx
 *	@param	TeamIdx
 *	@param	PokeIdx
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void OBJ_TransPokeGra( PKTHLN_PTR work, HEAPID HeapID, CATS_ACT_PTR cap, u8 NetID, u8 PokeID )
{
	MONS_INFO info;
	PTFrame_SetMonsInfo( work, NetID, PokeID, &info );
	CATS_PokeGraTrans( cap, &info, FALSE, FALSE, HeapID );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	ポケアイコンを転送
 *
 *	@param	DROP_SUB_CNT_PTR ptr
 *	@param	NetID
 *	@param	PokeIdx
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void OBJ_TransPokeIcon( DROP_SUB_CNT_PTR ptr, u8 NetID, u8 PokeIdx )
{
	MONS_INFO info;
	CATS_ACT_PTR act  = ptr->cap[ CAP_ID_POKE_HEAD + NetID ];

	// ポケモン情報を取得
	PTFrame_SetMonsInfo( ptr->work, NetID, PokeIdx, &info );

	// ポケアイコン転送
	CATS_PokeIconTrans( act, &info, ptr->PlttOfsPokeIcon, ptr->pArcPokeIcon, 0x20*4*4*NetID, ptr->HeapID );
}

//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	CATS_SYS_PTR csp
 *	@param	crp
 *	@param	px
 *	@param	py
 *	@param	anime
 *	@param	pri
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static CATS_ACT_PTR OBJ_AddCapMain( CATS_SYS_PTR csp, CATS_RES_PTR crp, s16 px, s16 py, u16 anime, u16 pri )
{
	TCATS_OBJECT_ADD_PARAM_S prm = {
		0, 0, 0,
		0, 0, 0, NNS_G2D_VRAM_TYPE_2DMAIN,
		{ CHR_ID_MAIN, PAL_ID_MAIN, CEL_ID_MAIN, ANM_ID_MAIN },
		1, 0,
	};

	CATS_ACT_PTR cap;

	GF_ASSERT(csp);
	GF_ASSERT(crp);

	prm.x = px;
	prm.y = py;
	prm.anm = anime;
	prm.pri = pri;

	cap = CATS_ObjectAdd_S_SubDistance( csp, crp, &prm, OBJ_DISTANCE );
	CATS_ObjectAutoAnimeSetCap( cap, TRUE );

	return cap;
}

//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	DROP_SUB_CNT_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void OBJ_CreateTime( DROP_SUB_CNT_PTR ptr )
{
	int i;

	ptr->cap[ CAP_ID_TIME_ICON ] = OBJ_AddCapMain( ptr->csp, ptr->crp, TIME_ICON_X, TIME_ICON_Y, NANR_drop_obj_main_time_cap, PRI_UI );
	CATS_ObjectPaletteSetCap( ptr->cap[ CAP_ID_TIME_ICON ], CATS_CMN_M_PALOFS + 1 );

	for( i=0; i<TIME_FIGRE; i++ )
	{
		VecFx32 vec = {0};

		ptr->actTime[i] = CmnRes_CreateF2X2Act( ptr->CmnResCntPtr, CATS_GetClactSetPtr(ptr->crp), PRI_UI, ptr->HeapID );

		// 座標
		vec.x = ( ( TIME_ICON_X + 16 + TIME_CAP_DIFF_X ) + 16 * i ) * FX32_ONE;
		vec.y = TIME_ICON_Y * FX32_ONE;
		vec.z = 0;
		CLACT_SetMatrix( ptr->actTime[i], &vec );

		CLACT_SetDrawFlag( ptr->actTime[i], 1 );
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief	BG ポケ名表示
 *
 *	@param	PKTHLN_DROP_PTR ptr
 *	@param	PokeID
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void ChangePokeName( DROP_SUB_CNT_PTR ptr, u8 PokeID )
{
//	OBJ_TransPokeIcon( ptr, ptr->NetID , PokeID );

	// 次のポケモン名を表示する
	PokeID = ( PokeID + 1 ) % ENTRY_MAX;

	WORDSET_RegisterWord( ptr->WordSet, 0, ptr->NickName[ PokeID ], PM_NEUTRAL, TRUE, PM_LANG );
	BMPWIN_Print( &ptr->Win[ WIN_ID_S_POKENICK ], ptr->WordSet, ptr->MsgMan, msg_pkthln_run_next, ptr->HeapID );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	ベンチポケモンと状態アイコンの位置をセットする
 *
 *	@param	u32 capID
 *	@param	px
 *	@param	py
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void SetBenchPokePos( DROP_SUB_CNT_PTR ptr, u32 capID, s16 px, s16 py )
{
	CATS_ObjectPosSetCap_SubSurface( ptr->cap[ capID ], px, py, OBJ_DISTANCE );
	py += BENCH_POKEEFF_Y_DIFF;
	// ※ポケグラ2体の直後がエフェクトになっている前提
	CATS_ObjectPosSetCap_SubSurface( ptr->cap[ capID + CAP_PKGR_MAX ], px, py, OBJ_DISTANCE );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	ポケアイコンの状態変更
 *
 *	@param	DROP_SUB_CNT_PTR ptr
 *	@param	NetID
 *	@param	bBall
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void SetPokeIconState( DROP_SUB_CNT_PTR ptr, u8 NetID, BOOL bBall )
{
	CATS_ObjectEnableCap( ptr->cap[ CAP_ID_POKE_HEAD + NetID ], !bBall );
	CATS_ObjectEnableCap( ptr->cap[ CAP_ID_BALL_HEAD + NetID ], bBall );
}

